module ysyx_22040213_MEMReg(
	input clk,
	input rst,
	
	input EXE_to_MEM_valid,
	input MEM_ready_go,
	input WB_allow_in,
	
	output MEM_allow_in,
	output MEM_to_WB_valid,
	
	input [63:0] i_mem_src2,
	input [63:0] i_mem_adata,
	input [2:0 ] i_mem_funct3,
	input i_mem_sm_en,
	input i_mem_lm_en,

	input [63:0] i_mem_pc_link,
	input [4:0] i_mem_rd,
	input i_mem_w_en,
	input [3:0] i_mem_RegWrite_en,
	input [63:0] i_mem_csr_src1,
	input i_mem_clint_hit,

	output [63:0] o_mem_src2,
	output [63:0] o_mem_adata,
	output [2:0 ] o_mem_funct3,
	output o_mem_sm_en,
	output o_mem_lm_en,

	output [63:0] o_mem_pc_link,
	output [4:0] o_mem_rd,
	output o_mem_w_en,
	output [3:0] o_mem_RegWrite_en,
	output [63:0] o_mem_csr_src1,
	output o_mem_clint_hit,

	//for difftest//
	input [31:0] i_mem_inst,
	input [63:0] i_mem_dnpc,
	input i_mem_id_bubble,
	input i_mem_exe_bubble,
	input i_mem_devices_access,

	output [31:0] o_mem_inst,
	output [63:0] o_mem_dnpc,
	output o_mem_id_bubble,
	output o_mem_exe_bubble,
	output o_mem_devices_access

);
	reg MEM_valid;

	assign MEM_allow_in = !MEM_valid || MEM_ready_go && WB_allow_in; 
	assign MEM_to_WB_valid = MEM_valid && MEM_ready_go;

	always @(posedge clk)begin
	  if(rst)begin
	    MEM_valid <= 1'b0;
	  end
	  else if(MEM_allow_in)begin
	    MEM_valid <= EXE_to_MEM_valid;
	  end
	end

	wire w_en;
	assign w_en = EXE_to_MEM_valid && MEM_allow_in;

	reg o_mem_w_en_i;
	assign o_mem_w_en = MEM_valid && o_mem_w_en_i;


	Reg #(64, 64'b0) i0 (clk, rst, i_mem_src2, o_mem_src2, w_en);
	Reg #(64, 64'b0) i1 (clk, rst, i_mem_adata, o_mem_adata, w_en);
	Reg #(3,  3 'b0) i2 (clk, rst, i_mem_funct3, o_mem_funct3, w_en);
	Reg #(1,  1 'b0) i3 (clk, rst, i_mem_sm_en, o_mem_sm_en, w_en);
	Reg #(1,  1 'b0) i4 (clk, rst, i_mem_lm_en, o_mem_lm_en, w_en);
	Reg #(5,  5 'b0) i5 (clk, rst, i_mem_rd, o_mem_rd, w_en);
	Reg #(1,  1 'b0) i6 (clk, rst, i_mem_w_en, o_mem_w_en_i, w_en);
	Reg #(64, 64'b0) i7 (clk, rst, i_mem_pc_link, o_mem_pc_link, w_en);
	Reg #(4,  4'b0 ) i8 (clk, rst, i_mem_RegWrite_en, o_mem_RegWrite_en, w_en);
	Reg #(1,  1'b0 ) i15 (clk, rst, i_mem_clint_hit, o_mem_clint_hit, w_en);
//for difftest//
	Reg #(32, 32'b0)  i9 (clk, rst, i_mem_inst, o_mem_inst, w_en);
	Reg #(64, 64'b0)  i10 (clk, rst, i_mem_dnpc, o_mem_dnpc, w_en);
	Reg #(1,   1'b0)  i11 (clk, rst, i_mem_id_bubble, o_mem_id_bubble, w_en);
	Reg #(1,   1'b0)  i12 (clk, rst, i_mem_exe_bubble, o_mem_exe_bubble, w_en);
	Reg #(64, 64'b0)  i13 (clk, rst, i_mem_csr_src1, o_mem_csr_src1, w_en);
	Reg #(1,   1'b0)  i14 (clk, rst, i_mem_devices_access, o_mem_devices_access, w_en);

endmodule
